package com.cashmama.market.api.application.controller.authentication.work;

import com.alibaba.fastjson.JSON;
import com.cashmama.market.api.application.controller.authentication.AuthenticationBaseHandler;
import com.cashmama.market.api.application.controller.authentication.AuthenticationController;
import com.cashmama.market.api.application.controller.authentication.personalInfo.InputContent;
import com.cashmama.market.api.application.controller.authentication.response.UserProfileResponse;
import com.cashmama.market.api.application.controller.authentication.vos.AuthenticationContentVo;
import com.cashmama.market.api.application.controller.authentication.vos.InputParams;
import com.cashmama.market.api.application.enums.AuthenticationTypeEnum;
import com.cashmama.market.api.application.enums.ButtonTextEnum;
import com.cashmama.market.api.application.enums.ParamType;
import com.cashmama.market.api.domain.service.ApiUserService;
import com.cashmama.market.api.domain.vo.RequestLocalInfo;
import com.cashmama.market.api.infras.enums.AuthOptionsEnums;
import com.cashmama.market.api.infras.enums.JumpRouterEnum;
import com.cashmama.market.api.infras.enums.error.UserProfileErrorCodeEnum;
import com.cashmama.market.api.infras.exception.ApplicationException;
import com.fqgj.common.utils.EmojiUtil;
import com.fqgj.common.utils.StrUtils;
import com.fqgj.xjd.user.client.UserInfoService;
import com.fqgj.xjd.user.client.enums.UserCareerEnum;
import com.fqgj.xjd.user.client.enums.UserEducationEnum;
import com.fqgj.xjd.user.client.enums.UserIndustryEnum;
import com.fqgj.xjd.user.client.enums.UserSalaryEnum;
import com.fqgj.xjd.user.client.request.UserBase;
import com.fqgj.xjd.user.client.request.UserWork;
import com.qianli.user.enums.UserAuthEnum;
import com.qianli.user.enums.UserAuthStatusEnum;
import com.qianli.user.ro.auth.UserAuthStatusRO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: yujianfu (mr.vencnet@gmail.com)
 * Date: 2019-12-23
 * Time: 09:56
 */
@Service
public class WorkAuthenticationHandler extends AuthenticationBaseHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(WorkAuthenticationHandler.class);

    public static final int ADDRESS_MIN_LENGTH = 10;
    public static final int PIN_CODE_LENGTH = 6;

    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private ApiUserService apiUserService;

    @PostConstruct
    public void init() {
        AuthenticationController.authenticationBaseHandlerMap.put(AuthenticationTypeEnum.WORK.getType(), this);
    }

    @Override
    public AuthenticationContentVo content() {
        AuthenticationContentVo authenticationContentVo = explain(new WorkInfo());
        authenticationContentVo.setButtonText(ButtonTextEnum.CONFIRM.getText());
        authenticationContentVo.setButtonVisibility(true);
        return authenticationContentVo;
    }

    @Override
    public UserProfileResponse save(Map<String, String> inputParams) {
        WorkInfo workInfo = new WorkInfo();
        getObject(workInfo,inputParams);
        doSave(workInfo);

        UserProfileResponse userProfileResponse = new UserProfileResponse()
                .setJumpUrl(this.getJumperUrl());
        return userProfileResponse;
    }

    private class WorkInfo {

        @InputContent(paramName = "Company Full Name", param = "companyFullName", inputDesc = "Please Input", paramType = ParamType.TEXT)
        private InputParams companyFullName;


        @InputContent(paramName = "Education Qualification", param = "educationQualification", paramType = ParamType.SELECT, operationEnum = AuthOptionsEnums.EDUCATION)
        private InputParams educationQualification;

        @InputContent(paramName = "Working Since", param = "workingStartDate", paramType = ParamType.DATE_PICK)
        private InputParams workingStartDate;

        @InputContent(paramName = "Occupation", param = "occupation", paramType = ParamType.SELECT, operationEnum = AuthOptionsEnums.WORK_TYPE)
        private InputParams occupation;

        @InputContent(paramName = "Industry", param = "industry", paramType = ParamType.SELECT, operationEnum = AuthOptionsEnums.INDUSTRY_TYPE)
        private InputParams industry;

        @InputContent(paramName = "Salary Range", param = "salaryRange", paramType = ParamType.SELECT, operationEnum = AuthOptionsEnums.SALARY_RANGE)
        private InputParams salaryRange;

        @InputContent(paramName = "Office Pin Code", param = "officePinCode", paramType = ParamType.TEXT, inputDesc = "Please Input")
        private InputParams officePinCode;

        @InputContent(paramName = "Office Address", param = "officeAddress", paramType = ParamType.TEXT, inputDesc = "Please Input")
        private InputParams officeAddress;

        public InputParams getIndustry() {
            return industry;
        }

        public WorkInfo setIndustry(InputParams industry) {
            this.industry = industry;
            return this;
        }

        public InputParams getOfficeAddress() {
            return officeAddress;
        }

        public WorkInfo setOfficeAddress(InputParams officeAddress) {
            this.officeAddress = officeAddress;
            return this;
        }

        public InputParams getSalaryRange() {
            return salaryRange;
        }

        public WorkInfo setSalaryRange(InputParams salaryRange) {
            this.salaryRange = salaryRange;
            return this;
        }

        public InputParams getOfficePinCode() {
            return officePinCode;
        }

        public WorkInfo setOfficePinCode(InputParams officePinCode) {
            this.officePinCode = officePinCode;
            return this;
        }

        public InputParams getCompanyFullName() {
            return companyFullName;
        }

        public WorkInfo setCompanyFullName(InputParams companyFullName) {
            this.companyFullName = companyFullName;
            return this;
        }

        public InputParams getEducationQualification() {
            return educationQualification;
        }

        public WorkInfo setEducationQualification(InputParams educationQualification) {
            this.educationQualification = educationQualification;
            return this;
        }

        public InputParams getWorkingStartDate() {
            return workingStartDate;
        }

        public WorkInfo setWorkingStartDate(InputParams workingStartDate) {
            this.workingStartDate = workingStartDate;
            return this;
        }

        public InputParams getOccupation() {
            return occupation;
        }

        public WorkInfo setOccupation(InputParams occupation) {
            this.occupation = occupation;
            return this;
        }
    }

    private void doSave(WorkInfo workInfo) {

        validate(workInfo);
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        UserCareerEnum userCareerEnum = UserCareerEnum.getEnumByType(Integer.valueOf(workInfo.getOccupation().getInputValue()));
        UserSalaryEnum userSalaryEnum = UserSalaryEnum.getEnumByType(Integer.valueOf(workInfo.getSalaryRange().getInputValue()));
        UserEducationEnum userEducationEnum = UserEducationEnum.getEnumByType(Integer.valueOf(workInfo.getEducationQualification().getInputValue()));
        UserIndustryEnum userIndustryEnum = UserIndustryEnum.getEnumByType(Integer.valueOf(workInfo.getIndustry().getInputValue()));
        UserWork userWork = new UserWork();
        userWork.setUserCode(userCode)
                .setCareerType(userCareerEnum.getType())
                .setCareer(userCareerEnum.getDesc())
                .setCompanyName(workInfo.getCompanyFullName().getInputValue())
                .setAddress(workInfo.getOfficeAddress().getInputValue())
                .setSalary(userSalaryEnum.getType())
                .setOfficePinCode(workInfo.getOfficePinCode().getInputValue())
                .setFromWhen(workInfo.getWorkingStartDate().getInputValue())
                .setIndustry(userIndustryEnum.getDesc())
                .setIndustryId(userIndustryEnum.getCode());

        UserBase userBase = new UserBase();
        userBase.setUserCode(userCode).setEducation(userEducationEnum.getType());
        userInfoService.updateUserBase(userBase);
        userInfoService.addUserWork(userWork);
        LOGGER.info("=====保存工作信息========={}", JSON.toJSONString(userWork));
        apiUserService.updateUserAuthStatus(UserAuthStatusEnum.SUCCESS, UserAuthEnum.BASE_WORK_STATUS, RequestLocalInfo.getCurrentUser().getUserCode());
    }

    private void validate(WorkInfo workInfo){
        if (workInfo.getEducationQualification().getInputValue() == null) {
            throw new ApplicationException("Highest Education should not be empty");
        }
        if (workInfo.getIndustry().getInputValue() == null) {
            throw new ApplicationException("Industry should not be empty");
        }
        if (!StrUtils.isNumeric(workInfo.getOfficePinCode().getInputValue()) || workInfo.getOfficePinCode().getInputValue().length() != PIN_CODE_LENGTH) {
            throw new ApplicationException("Please enter the correct officePinCode");
        }
        if (StringUtils.isBlank(workInfo.getOfficeAddress().getInputValue())) {
            throw new ApplicationException("Please enter the correct address");
        }
        String officeAddress = EmojiUtil.filterEmoji(workInfo.getOfficeAddress().getInputValue());
        if (officeAddress.trim().length() < ADDRESS_MIN_LENGTH || officeAddress.contains("@")) {
            throw new ApplicationException("Please enter the correct address");
        }
        if(!StrUtils.isNumeric(workInfo.getOccupation().getInputValue())){
            throw new ApplicationException("Please enter the correct occupation");
        }
        if(!StrUtils.isNumeric(workInfo.getSalaryRange().getInputValue())){
            throw new ApplicationException("Please enter the correct salary range");
        }
        if(!StrUtils.isNumeric(workInfo.getEducationQualification().getInputValue())){
            throw new ApplicationException("Please enter the correct education");
        }
        UserCareerEnum userCareerEnum = UserCareerEnum.getEnumByType(Integer.valueOf(workInfo.getOccupation().getInputValue()));
        UserSalaryEnum userSalaryEnum = UserSalaryEnum.getEnumByType(Integer.valueOf(workInfo.getSalaryRange().getInputValue()));
        UserEducationEnum userEducationEnum = UserEducationEnum.getEnumByType(Integer.valueOf(workInfo.getEducationQualification().getInputValue()));
        if (userCareerEnum == null || userSalaryEnum == null || userEducationEnum == null) {
            throw new ApplicationException(UserProfileErrorCodeEnum.USER_PROFILE_ENUM_TYPE_NOT_EXIST);
        }

    }

    private String getJumperUrl(){
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        UserAuthStatusRO userAuthStatusRO = apiUserService.getUserAuthStatus(userCode);
        boolean kycComplete = apiUserService.kycActionComplete(userAuthStatusRO);
        boolean bankComplete = userAuthStatusRO.getBankStatus() == UserAuthStatusEnum.SUCCESS.getCode();
        if(!kycComplete){
            return JumpRouterEnum.KYC_DOCUMENTS_AADHAAR.getJumpUrl();
        }else if(kycComplete && !bankComplete){
            return JumpRouterEnum.PERSONAL_INFO_BANK.getJumpUrl();
        }else{
            return JumpRouterEnum.HOME.getJumpUrl();
        }
    }

}
